#include "bflb_gpio.h"
#include "bflb_joystick.h"

struct bflb_device_s *adc_joystick;
struct bflb_device_s *gpio_joystick; //初始化一个结构体指针作为外设句柄

void generate_adc_channels(int pin_x, int pin_y, struct bflb_adc_channel_s chan[]) {  
    // 构建一个pin引脚到通道的映射
    chan[0].neg_chan = ADC_CHANNEL_GND;
    chan[1].neg_chan = ADC_CHANNEL_GND;

    // 根据pin_x和pin_y输出对应pos_chan
    switch (pin_x) {  
        case GPIO_PIN_20:  
            chan[0].pos_chan = ADC_CHANNEL_0;
            break;  
        case GPIO_PIN_19:  
            chan[0].pos_chan = ADC_CHANNEL_1; 
            break;  
        case GPIO_PIN_14:  
            chan[0].pos_chan = ADC_CHANNEL_4;
            break;
        case GPIO_PIN_13:  
            chan[0].pos_chan = ADC_CHANNEL_5;
            break;  
        case GPIO_PIN_12:  
            chan[0].pos_chan = ADC_CHANNEL_6; 
            break;  
        case GPIO_PIN_10:  
            chan[0].pos_chan = ADC_CHANNEL_7;
            break;
        case GPIO_PIN_1:  
            chan[0].pos_chan = ADC_CHANNEL_8;
            break;  
        case GPIO_PIN_0:  
            chan[0].pos_chan = ADC_CHANNEL_9; 
            break;  
        case GPIO_PIN_27:  
            chan[0].pos_chan = ADC_CHANNEL_10;
            break;
        case GPIO_PIN_28:  
            chan[0].pos_chan = ADC_CHANNEL_11;
            break;
    }
    switch (pin_y) {  
        case GPIO_PIN_20:  
            chan[1].pos_chan = ADC_CHANNEL_0;
            break;  
        case GPIO_PIN_19:  
            chan[1].pos_chan = ADC_CHANNEL_1; 
            break;  
        case GPIO_PIN_14:  
            chan[1].pos_chan = ADC_CHANNEL_4;
            break;
        case GPIO_PIN_13:  
            chan[1].pos_chan = ADC_CHANNEL_5;
            break;  
        case GPIO_PIN_12:  
            chan[1].pos_chan = ADC_CHANNEL_6; 
            break;  
        case GPIO_PIN_10:  
            chan[1].pos_chan = ADC_CHANNEL_7;
            break;
        case GPIO_PIN_1:  
            chan[1].pos_chan = ADC_CHANNEL_8;
            break;  
        case GPIO_PIN_0:  
            chan[1].pos_chan = ADC_CHANNEL_9; 
            break;  
        case GPIO_PIN_27:  
            chan[1].pos_chan = ADC_CHANNEL_10;
            break;
        case GPIO_PIN_28:  
            chan[1].pos_chan = ADC_CHANNEL_11;
            break;
    }
}  

void bflb_joystick_init(uint8_t pin_x, uint8_t pin_y, uint8_t pin_sw){

    struct bflb_adc_channel_s chan[2];
    generate_adc_channels(pin_x, pin_y, chan);

    gpio_joystick = bflb_device_get_by_name("gpio");
    adc_joystick = bflb_device_get_by_name("adc");

    bflb_gpio_init(gpio_joystick, pin_x, GPIO_ANALOG | GPIO_SMT_EN | GPIO_DRV_0);
    bflb_gpio_init(gpio_joystick, pin_y, GPIO_ANALOG | GPIO_SMT_EN | GPIO_DRV_0);
    bflb_gpio_init(gpio_joystick, pin_sw, GPIO_INPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0);

    /* adc clock = XCLK / 2 / 32 */
    //ADC的一些配置
    struct bflb_adc_config_s cfg;
    cfg.clk_div = ADC_CLK_DIV_32;
    cfg.scan_conv_mode = true;
    cfg.continuous_conv_mode = false;
    cfg.differential_mode = false;
    cfg.resolution = ADC_RESOLUTION_16B;
    cfg.vref = ADC_VREF_3P2V;

    bflb_adc_init(adc_joystick, &cfg);
    bflb_adc_channel_config(adc_joystick, chan, 2);
}


void bflb_joystick_read(struct bflb_joystick_attr* values, uint8_t pin_sw){
	bflb_adc_start_conversion(adc_joystick); // 开启adc采集

	while (bflb_adc_get_count(adc_joystick) < 2) {
		bflb_mtimer_delay_ms(1);  // 将adc队列采集完毕
	}

	uint32_t raw_data_x = bflb_adc_read_raw(adc_joystick); // FIFO中读取第一次采集数据
	bflb_adc_parse_result(adc_joystick, &raw_data_x, &values->result_x, 1);
	uint32_t raw_data_y = bflb_adc_read_raw(adc_joystick);  // FIFO中读取第二次采集数据
	bflb_adc_parse_result(adc_joystick, &raw_data_y, &values->result_y, 1);
	values->result_sw = bflb_gpio_read(gpio_joystick, pin_sw);  // 读取GPIO_PIN状态
	bflb_adc_stop_conversion(adc_joystick);
}
